"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

import Pyro.core
from msnp.service.network.model.Model import ConnectionType
from msnp.service.network.model.RemoteModel import Authentication, PeerUpdate, Crash, Fingertable, ResponsibilitySearch, MessageExchange, \
    Backup, GroupManagement
from msnp.service.network.listening.Listener import ListeningThread
from msnp.logger import Logger
import traceback

def createDaemon(myPort):
    """Initializes the daemons.
    
    This function creates eight daemons listening on different ports, depending on which are available.
    
    Args:
        myPort: The preferred port number for the first daemon

    Returns:
        A dictionary containing the daemons. None if an exception occurred.
    """
    try:
        ListeningThread.stopListening()
        Pyro.core.initServer()
        Pyro.config.PYRO_PORT_RANGE = 1000
        
        exchangeDaemon = Pyro.core.Daemon(port=int(myPort))
        authDaemon = Pyro.core.Daemon(port=int(myPort))
        respDaemon = Pyro.core.Daemon(port=int(myPort))
        peerUpdateDaemon = Pyro.core.Daemon(port=int(myPort))
        fingerDaemon = Pyro.core.Daemon(port=int(myPort))
        backupDaemon = Pyro.core.Daemon(port=int(myPort))
        crashDaemon = Pyro.core.Daemon(port=int(myPort))
        groupDaemon = Pyro.core.Daemon(port=int(myPort))

        exchangeDaemon.setTimeout(5)
        authDaemon.setTimeout(5)
        respDaemon.setTimeout(5)
        peerUpdateDaemon.setTimeout(5)
        fingerDaemon.setTimeout(5)
        backupDaemon.setTimeout(5)
        crashDaemon.setTimeout(5)
        groupDaemon.setTimeout(5)
        
        exchangeDaemon.connect(MessageExchange(), ConnectionType.MESSAGE_EXCHANGE)
        authDaemon.connect(Authentication(), ConnectionType.AUTHENTICATION)
        respDaemon.connect(ResponsibilitySearch(), ConnectionType.RESPONSIBILITY_SEARCH)
        peerUpdateDaemon.connect(PeerUpdate(), ConnectionType.PEERUPDATE)
        fingerDaemon.connect(Fingertable(), ConnectionType.FINGERTABLE)
        backupDaemon.connect(Backup(), ConnectionType.BACKUP)
        crashDaemon.connect(Crash(), ConnectionType.CRASH)
        groupDaemon.connect(GroupManagement(), ConnectionType.GROUP_MANAGEMENT)
        
        ListeningThread.addThread(ListeningThread(authDaemon))
        ListeningThread.addThread(ListeningThread(respDaemon))
        ListeningThread.addThread(ListeningThread(peerUpdateDaemon))
        ListeningThread.addThread(ListeningThread(fingerDaemon))
        ListeningThread.addThread(ListeningThread(backupDaemon))
        ListeningThread.addThread(ListeningThread(crashDaemon))
        ListeningThread.addThread(ListeningThread(exchangeDaemon))
        ListeningThread.addThread(ListeningThread(groupDaemon))
        
        ListeningThread.startListening()
        
        returnDict = {}
        returnDict[ConnectionType.AUTHENTICATION] = authDaemon.port
        returnDict[ConnectionType.RESPONSIBILITY_SEARCH] = respDaemon.port
        returnDict[ConnectionType.PEERUPDATE] = peerUpdateDaemon.port
        returnDict[ConnectionType.BACKUP] = backupDaemon.port
        returnDict[ConnectionType.CRASH] = crashDaemon.port
        returnDict[ConnectionType.FINGERTABLE] = fingerDaemon.port
        returnDict[ConnectionType.MESSAGE_EXCHANGE] = exchangeDaemon.port
        returnDict[ConnectionType.GROUP_MANAGEMENT] = groupDaemon.port
        return returnDict
    except:
        Logger.info("Error while creating daemons")
        traceback.print_exc()
    return None

   

